package com.xia.manager.service;

import com.cy.entity.Product;
import com.cy.entity.enums.ProductStatus;
import com.xia.manager.error.ErrorEnum;
import com.xia.manager.repositories.ProductRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.persistence.criteria.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName ProductService
 * @Deserintion TDDO
 * @Author ciyuan
 * @Date 2018/11/25/025 1:05
 **/
@Slf4j
@Service
public class ProductService {

    @Autowired
    private ProductRepository repository;

    /**
     * 添加单个产品
     * @param product
     * @return
     */
    public Product addProduct(Product product){
        log.debug("创建产品，参数=【{}】",product);
        //数据校验
        checkProduct(product);
        //设置默认值
        setDefault(product);
        Product result = repository.save(product);
        log.debug("创建产品，结果=【{}】",result);
        return result;
    }

    /**
     * 查询单个商品
     * @param id 产品编号
     * @return 返回单个产品或者空
     */
    public Product findOne(String id){
        Assert.notNull(id,"需要产品编号参数");
        log.debug("查询单个产品，id=【{}】",id);
        Product result = repository.findOne(id);
        log.debug("查询单个产品，结果=【{}】",result);
        return result;
    }

    /**
     * 分页查询产品
     * @param idList id集合
     * @param minRewardRate 最小收益率
     * @param maxRewardRate 最大收益率
     * @param statusList 状态集合
     * @param pageable 分页信息
     * @return
     */
    public Page<Product> query(List<String> idList,
                               BigDecimal minRewardRate, BigDecimal maxRewardRate,
                               List<String> statusList,
                               Pageable pageable){
        log.debug("查询产品，idList=【{}】，最小收益率=【{}】，最大收益率=【{}】，statusList=【{}】，pageable=【{}】",idList,minRewardRate,maxRewardRate,statusList,pageable);

        Specification<Product> specification = new Specification<Product>() {
            @Override
            public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Expression<String> idCol = root.get("id");
                Expression<BigDecimal> rewardRateCol = root.get("rewardRate");
                Expression<String> status = root.get("status");
                List<Predicate> predicates = new ArrayList<>();
                if (idList != null && idList.size() > 0) {
                    predicates.add(idCol.in(idList));
                }
                if (null!=minRewardRate&&BigDecimal.ZERO.compareTo(minRewardRate)<0){
                    predicates.add(cb.ge(rewardRateCol,minRewardRate));
                }
                if (null!=maxRewardRate&&BigDecimal.ZERO.compareTo(maxRewardRate)<0){
                    predicates.add(cb.le(rewardRateCol,maxRewardRate));
                }
                if (null!=statusList && statusList.size() > 0) {
                    predicates.add(status.in(statusList));
                }
                query.where(predicates.toArray(new Predicate[0]));
                return null;
            }
        };
        Page<Product> page = repository.findAll(specification,pageable);
        log.debug("查询产品，结果=【{}】",page);
        return page;
    }

    /**
     * 设置默认值
     * 创建时间、更新时间
     * 投资步长、锁定期、状态
     * @param product
     */
    private void setDefault(Product product) {
        if (product.getCreateAt() == null) {
            product.setCreateAt(new Date());
        }
        if (product.getUpdateAt() == null) {
            product.setUpdateAt(new Date());
        }
        if (product.getStepAmount() == null) {
            product.setStepAmount(BigDecimal.ZERO);
        }
        if (product.getLockTerm() == null) {
            product.setLockTerm(0);
        }
        if (product.getStatus() == null) {
            product.setStatus(ProductStatus.AUDITING.name());
        }

    }

    /**
     * 产品数据校验
     * 1.非空数据
     * 2.收益率0-30之类
     * 3.投资步长需为整数
     * @param product
     */
    private void checkProduct(Product product) {
        //id非空校验
        Assert.notNull(product.getId(),ErrorEnum.ID_NOT_NULL.getCode());

        //其它非空校验
        Assert.isTrue(BigDecimal.ZERO.compareTo(product.getRewardRate())<0&&BigDecimal.valueOf(30).compareTo(product.getRewardRate())>0,"收益率范围错误");
        Assert.isTrue(BigDecimal.valueOf(product.getStepAmount().longValue()).compareTo(product.getStepAmount())==0,"投资步长需为整数");

    }
}
